<?php
require_once dirname(__FILE__) . '/libraries/ServiceBase.php';
/**
 * 支付统一接口api
 */
#@todo
class SDOServicePayment extends ServiceBase
{ 
    const PAYMENT_WSDL = 'PAYMENT_WSDL';
    const PRE_PAYMENT_WSDL = 'PRE_PAYMENT_WSDL';
    /**
     * 获取用户剩余点券
     *
     * @param string $message
     * @param string $ptid
     * @return int|boolean
     */
    public static function accountAuthen (&$message, $ptid, $env = 'pre')
    {
        $wsdl = $env === 'pre' ? sdk_fetch_config(SDK_ENV . self::PRE_PAYMENT_WSDL) : sdk_fetch_config(SDK_ENV . self::PAYMENT_WSDL);
        $param['uidType'] = 1;
        $param['userId'] = $ptid;
        $param['spId'] = 1;
        $param['areaIdPlayer'] = 0;
        $param['servIdPlayer'] = 0;
        $param['orderId'] = md5(microtime(TRUE) . rand(10000, 99999));
        $param['endpointIp'] = ip_get_real();
        $param['callTime'] = date('Y-m-d H:i:s');
        $param['indicationAuthen'] = 2;
        # 3 盛大点券
        $param['payType'] = 3;
        $param['coupleType'] = 1;
        # 1 PC ,2 Mobile
        $param['endpointType'] = 1;
        # 1 PC ,2 EZHOME
        $param['platformType'] = 1;
        # unknown param
        $param['groupIdPlayer'] = 0;
        $param['reserveInt'] = 1;
        $param['reserveString'] = 1;
        $param['userType'] = 1;
        $option['soap_version'] = SOAP_1_1;
        if (isset($wsdl['options']) && $wsdl['options']) {
            $option = array_merge($option, $wsdl['options']);
        }
        $result = self::soapRequest('accountAuthen', $param, $wsdl['wsdl'], $option, $message);
        //$soap = new SoapClient($wsdl, $option);
        //$result = $soap->accountAuthen($param);
        if ($result === FALSE) {
            self::log("method: ".__FUNCTION__."\tparams: ".json_encode($param)."\tenv: {$env}\texception: ".$message, __CLASS__);
            return FALSE;
        }
        if ($result->result !== 0 &&$result->result !== -106908) {
            $message = self::_authenError($result->result, $message);
            self::log("method: ".__FUNCTION__."\tparams: ".json_encode($param)."\tenv: {$env}\treturn: ".json_encode($result), __CLASS__);
            return FALSE;
        }
        self::log("method: ".__FUNCTION__."\tparams: ".json_encode($param)."\tenv: {$env}\treturn: ".json_encode($result), __CLASS__, true);
        return self::_getRemainCoin($result->balanceInfo, $message);
    }
    /**
     * 批量获取用户剩余点券
     * @param array $ptList
     * 
     * @return array(uid=>array('result'=>123, 'msg'=>出错信息), ,,,)
     */
    public function getUserAccountMulti($ptList, $env='pre')
    {
        $result = array();
        $row = array('result'=>0, 'msg'=>'');
        foreach($ptList as $pt){
            $row['result'] = self::accountAuthen($row['msg'], $pt, $env);
            $result[$pt] = $row;   
        }
        return $result;
    }
    /**
     * 获取余额
     *
     * @param string $balanceInfo
     * @param string $message
     * @return int|boolean
     */
    private function _getRemainCoin ($balanceInfo, &$message)
    {
        $remain = explode('|', $balanceInfo, '2');        
        if ($remain[0] && ! isset($remain[1])) {
            $message = '余额获取错误！';
            return FALSE;
        } else {
            return (int) $remain[1];
        }
    }
    /**
     * 冻结点券
     *
     * @param string $message
     * @param string $ptid
     * @param string $order_id
     * @param int $price
     * @param int $appId
     * @param int $areaId
     * @param int $spId
     * @return boolean
     */
    public static function accountLock (&$message, $ptid, $orderId, $price, $appId = 999, $areaId = 1, $spId = 1, $env = 'pre')
    {
        $wsdl = $env === 'pre' ? sdk_fetch_config(SDK_ENV . self::PRE_PAYMENT_WSDL) : sdk_fetch_config(SDK_ENV . self::PAYMENT_WSDL);
        $option['soap_version'] = 'SOAP_1_1';
        $param['uidType'] = 1;
        $param['userId'] = $ptid;
        $param['contextId'] = sprintf("%'@-32s", $orderId);
        $param['orderId'] = md5(microtime(TRUE) . rand(10000, 99999));
        $param['spId'] = $spId;
        $param['servIdPlayer'] = $appId;
        $param['areaIdPlayer'] = $areaId;
        $param['groupIdPlayer'] = 0;
        #@todo 需申请
        $param['appType'] = 15;
        $param['coupleType'] = 2;
        $param['payInfo'] = "3|{$price}";
        $param['discount'] = 100;
        $param['feeInfo'] = '';
        $param['lockPeriod'] = - 1;
        # 1 PC ,2 Mobile
        $param['endpointType'] = 1;
        $param['endpointIp'] = ip_get_real();
        # 1 PC ,2 EZHOME
        $param['platformType'] = 1;
        $param['callTime'] = date('Y-m-d H:i:s');
        $param['indicationLock'] = 1;
        $param['goodsNum'] = 1;
        $param['goodsInfo'] = "1,{$appId},{$areaId},0,1,{$price}";
        $param['lockedDetailInfoFlag'] = 1;
        $param['reserveInt'] = 1;
        $param['reserveString'] = 1;
        $option['soap_version'] = 'SOAP_1_1';
        if (isset($wsdl['options']) && $wsdl['options']) {
            $option = array_merge($option, $wsdl['options']);
        }
        $result = self::soapRequest('accountLock', $param, $wsdl['wsdl'], $option, $message);
        if ($result === FALSE) {
            self::log("method: ".__FUNCTION__."\tparams: ".json_encode($param)."\tenv: {$env}\texception: ".$message, __CLASS__);
            return FALSE;
        }
        #var_dump($result);
        if ($result->result !== 0) {
            $message = self::_lockError($result->result);
            self::log("method: ".__FUNCTION__."\tparams: ".json_encode($param)."\tenv: {$env}\treturn: ".json_encode($result), __CLASS__);
            return FALSE;
        }
        self::log("method: ".__FUNCTION__."\tparams: ".json_encode($param)."\tenv: {$env}\treturn: ".json_encode($result), __CLASS__, true);
        return TRUE;
    }
    /**
     * 解冻点券
     *
     * @param string $message
     * @param string $ptid
     * @param string $order_id
     * @param int $price
     * @param int $confirm
     * @param int $appId
     * @param int $areaId
     * @param int $spId
     * @return boolean
     */
    public static function accountUnlock (&$message, $ptid, $order_id, $price, $confirm, $appId = 999, $areaId = 1, $spId = 1, $env = 'pre')
    {
        $wsdl = $env === 'pre' ? sdk_fetch_config(SDK_ENV . self::PRE_PAYMENT_WSDL) : sdk_fetch_config(SDK_ENV . self::PAYMENT_WSDL);
        $option['soap_version'] = 'SOAP_1_1';
        $param['uidType'] = 1;
        $param['userId'] = $ptid;
        $param['contextId'] = sprintf("%'@-32s", $order_id);
        $param['orderId'] = md5(microtime(TRUE) . rand(10000, 99999));
        $param['spId'] = $spId;
        $param['servIdPlayer'] = $appId;
        $param['areaIdPlayer'] = $areaId;
        $param['groupIdPlayer'] = 0;
        #@todo 需申请
        $param['appType'] = 15;
        $param['coupleType'] = 2;
        $param['payInfo'] = "3|{$price}";
        $param['feeInfo'] = '';
        $param['confirm'] = $confirm;
        # 1 PC ,2 Mobile
        $param['endpointType'] = 1;
        $param['endpointIp'] = ip_get_real();
        # 1 PC ,2 EZHOME
        $param['platformType'] = 1;
        $param['callTime'] = date('Y-m-d H:i:s');
        $param['indicationUnlock'] = 1;
        $param['goodsNum'] = 1;
        $param['goodsInfo'] = "1,{$appId},{$areaId},0,1,{$price}";
        $param['lockedDetailInfoFlag'] = 1;
        $param['reserveInt'] = 1;
        $param['reserveString'] = 1;
        $option['soap_version'] = 'SOAP_1_1';
        if (isset($wsdl['options']) && $wsdl['options']) {
            $option = array_merge($option, $wsdl['options']);
        }
        $result = self::soapRequest('accountUnlock', $param, $wsdl['wsdl'], $option, $message);
        if ($result === FALSE) {
            self::log("method: ".__FUNCTION__."\tparams: ".json_encode($param)."\tenv: {$env}\texception: ".$message, __CLASS__);
            return FALSE;
        }
        if ($result->result !== 0) {
            $message = self::_unlockError($result->result);
            self::log("method: ".__FUNCTION__."\tparams: ".json_encode($param)."\tenv: {$env}\treturn: ".json_encode($result), __CLASS__);
            return FALSE;
        }
        self::log("method: ".__FUNCTION__."\tparams: ".json_encode($param)."\tenv: {$env}\treturn: ".json_encode($result), __CLASS__, true);
        $message = $confirm;
        return self::_getRemainCoin($result->balanceInfo, $message)!==FALSE;
    }
    /**
     * 解冻点券错误信息
     *
     * @param int $id
     * @return string
     */
    private function _unlockError ($id)
    {
        $error = array(
            - 106201 => '预冻记录不存在,或流程已移入历史' , 
            - 106202 => '传入数字账号格式错误' , 
            - 106203 => '传入PT格式错误' , 
            - 106204 => '预冻记录已确认' , 
            - 106205 => '预冻记录已取消' , 
            - 106206 => '预冻记录已处理' , 
            - 106208 => '预冻与解冻参数不符' , 
            - 106209 => '发现多条预冻记录' , 
            - 106210 => '查找总账号元宝的汇率转换关系出错(rateex配置问题)' , 
            - 106211 => '玩家帐户不存在' , 
            - 106213 => '玩家预冻余额不足' , 
            - 106214 => '记录item明细日志时出错' , 
            - 106216 => '传入orderid重复' , 
            - 106217 => '传入解冻金额必须大于零' , 
            - 106218 => '不支持该解冻指令编码' , 
            - 106219 => '不支持该解冻确认参数' , 
            - 106220 => '账户类型配置错误' , 
            - 106221 => '多次解冻指令只能在取消的时候使用' , 
            - 106222 => '确认玩家预冻金额出错' , 
            - 106223 => '回滚预冻剩余金额时出错' , 
            - 106224 => '确认流程时出错' , 
            - 106225 => '取消预冻时出错' , 
            - 106226 => '记录付费日志出错' , 
            - 106227 => '确定帐户类型和汇率时出错' , 
            - 106228 => '帐户类型与预冻不符' , 
            - 106291 => '解冻预冻冻的重要参数不符' , 
            - 106297 => '传入参数存在空值' , 
            - 106298 => '传入参数超出最大长度限制或为空' , 
            - 106299 => '数据库异常' , 
            - 1 => '未知错误'
        );
        if (isset($error[$id])) {
            return $error[$id];
        }
        return $error[- 1];
    }
    /**
     * 冻结点券错误信息
     *
     * @param int $id
     * @return string
     */
    private function _lockError ($id)
    {
        $error = array(
            - 2 => '参数格式错误' , 
            - 3 => '无访问权限' , 
            - 4 => '程序异常' , 
            - 5 => '分红消耗超出限额' , 
            - 106101 => '传入预冻金额必须大于零' , 
            - 106103 => '传入预冻时长非法必须>=-1' , 
            - 106104 => '传入数字账号格式错误' , 
            - 106105 => '传入PT格式错误' , 
            - 106106 => '传入itemid格式错误' , 
            - 106107 => '传入orderid重复' , 
            - 106108 => '传入游戏不存在' , 
            - 106109 => '传入游戏区不存在' , 
            - 106110 => '传入contextid已经处理' , 
            - 106111 => '查找总账号元宝的汇率转换关系出错(rateex配置问题)' , 
            - 106112 => '玩家帐户不存在' , 
            - 106113 => '玩家帐户余额不存在' , 
            - 106114 => '玩家帐户余额不足' , 
            - 106115 => '不支持该预冻指令编码' , 
            - 106116 => '账户类型配置错误' , 
            - 106117 => '传入的耦合类型不支持' , 
            - 106118 => '没有找到tbpayfilter的对应关系' , 
            - 106119 => '预冻金额出错' , 
            - 106120 => '记录付费日志出错' , 
            - 106121 => '确认预冻时出错' , 
            - 106122 => '记录item明细日志时出错' , 
            - 106123 => '传入的paytypeid不支持' , 
            - 106124 => '确定帐户类型和汇率时出错' , 
            - 106125 => '新建预冻记录时出错' , 
            - 106126 => '该应用类型只应用于银行卡专区购买' , 
            - 106127 => '该银行卡专区业务只能用于总帐点券扣费' , 
            - 106128 => '玩家银行卡帐户余额不存在' , 
            - 106129 => '玩家银行卡帐户余额不足' , 
            - 106130 => '没有找到银行卡tbpayfilter的对应关系' , 
            - 106131 => '记录银行卡付费日志出错' , 
            - 106132 => '新建银行卡预冻记录时出错' , 
            - 106133 => '预冻银行卡金额出错' , 
            - 106134 => '参数与冻结不符' , 
            - 106135 => '帐户类型与预冻不符' , 
            - 106136 => '预冻记录不存在,或流程已移入历史' , 
            - 106137 => '发现多条预冻记录' , 
            - 106197 => '传入参数存在空值' , 
            - 106198 => '传入参数超出最大长度限制或为空' , 
            - 106199 => '数据库异常' , 
            - 1 => '未知错误'
        );
        if (isset($error[$id])) {
            return $error[$id];
        }
        return $error[- 1];
    }
    /**
     * 余额错误信息
     *
     * @param int $id
     * @return string
     */
    private function _authenError ($id)
    {
        $error = array(
            - 106901 => '传入数字账号格式错误' , 
            - 106902 => '传入PT格式错误' , 
            - 106903 => '传入游戏不存在' , 
            - 106904 => '传入游戏区不存在' , 
            - 106905 => '该游戏没有配置有效认证paytypeid,或配置错误' , 
            - 106906 => '该游戏认证paytypeid配置错误' , 
            - 106907 => '对应的paytypeid没有配置账号类型' , 
            - 106908 => '该账号没有余额或对应账号不存在' , 
            - 106910 => '查找总账号元宝的汇率转换关系出错(rateex配置问题)' , 
            - 106911 => '传入的耦合类型不支持' , 
            - 106912 => '传入的paytypeid不支持' , 
            - 106913 => 'AION时长不支持全区认证' , 
            - 106914 => 'TBAIONDEPOSITCFG表配置信息不存在' , 
            - 106915 => '根据TBAIONDEPOSITCFG表配置信息建立数据库连接失败' , 
            - 106916 => 'AION账号不存在' , 
            - 106917 => 'AION时长认证indication只能是4' , 
            - 106918 => '进行数据库操作的时候发生异常' , 
            - 106997 => '传入参数存在空值' , 
            - 106998 => '传入参数超出最大长度限制或为空' , 
            - 106999 => '数据库异常' , 
            - 1 => '未知错误'
        );
        if (isset($error[$id])) {
            return $error[$id];
        }
        return $error[- 1];
    }
	/**
     * 自检函数
     */
    public static function selfTest() 
    {
    	$sdk1 = sdk_fetch_config(SDK_ENV . self::PAYMENT_WSDL);
    	$sdk2 = sdk_fetch_config(SDK_ENV . self::PRE_PAYMENT_WSDL);
    	return self::curlTest(array($sdk1['wsdl'],$sdk2['wsdl']));
    }
}
/**
 * 获取IP
 *
 * @return unknown
 */
function ip_get_real ()
{
    if (! empty($_SERVER["HTTP_X_FORWARDED_FOR"])) {
        $ipstr = $_SERVER["HTTP_X_FORWARDED_FOR"];
        $iparr = explode(',', $ipstr);
        $ip = $iparr[0];
    } elseif (! empty($_SERVER["HTTP_CLIENT_IP"])) {
        $ip = $_SERVER["HTTP_CLIENT_IP"];
    } elseif (! empty($_SERVER["REMOTE_ADDR"])) {
        $ip = $_SERVER["REMOTE_ADDR"];
    } elseif (getenv("HTTP_X_FORWARDED_FOR")) {
        $ip = getenv("HTTP_X_FORWARDED_FOR");
    } elseif (getenv("HTTP_CLIENT_IP")) {
        $ip = getenv("HTTP_CLIENT_IP");
    } elseif (getenv("REMOTE_ADDR")) {
        $ip = getenv("REMOTE_ADDR");
    } else {
        $ip = "Unknown";
    }
    if (strpos($ip, ',') !== FALSE) {
        $ips = explode(',', $ip);
        $ip = trim($ips[0]);
    }
    return $ip;
}
